package com.njworkorder.HTSingleLogin;

import com.qingstor.sdk.exception.QSException;
import com.qingstor.sdk.service.Bucket;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.UUID;

/**
 * 青云上传工具类
 *
 * @author ht_lzc
 * @date 2024/12/20 20:12
 */
@Slf4j
public class QyOssUtil {
    public static FileInfo uploadFile(Bucket qyBucket, String qyBucketName, String qyZoneName, MultipartFile file) {
        FileInfo fileInfo = new FileInfo();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date nowDate = DateUtils.getNowDate();
        String format = sdf.format(nowDate);

        Bucket.PutObjectInput input = new Bucket.PutObjectInput();
        try {
            InputStream body = file.getInputStream();
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            // 这里只起示例作用, 如果 body size 有可能非常大, 按一定 size 做拆分以分段
            // 上传形式来分 part 计算 md5 上传才是比较经济的方式.
            byte[] data = body.readAllBytes();
            String contentMD5 = Base64.getEncoder().encodeToString(md5.digest(data));
            input.setContentMD5(contentMD5);
            // 此时 stream 已经被 consume 掉, 但对象存储 server side 也需要读取 body 内容,
            //  所以在 setBodyInputStream 之前,  可以通过:
            //  1. 流已经读取为 bytes array, 直接构造 ByteArrayInputStream 即可;
            body = new ByteArrayInputStream(data);
            //  2. 如果流支持 markSupported(), 可以重设到流的开始.
            //  下面是方式 2 的示例:
            body.reset();
            input.setBodyInputStream(body);
            String originalFilename = file.getOriginalFilename();
            String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            String id = UUID.randomUUID().toString();
            String newFileName = id + "." + suffix;
            newFileName = format + "/" + newFileName;

            Bucket.PutObjectOutput output = qyBucket.putObject(newFileName, input);
            log.info("output: " + output);
            System.out.println(output.getStatueCode());
            if (output.getStatueCode() == 201) {
                log.info("文件上传成功!");
                String filePath = String.format("https://%s.%s.qingstor.com/%s", qyBucketName, qyZoneName, newFileName);

                fileInfo.setFilePath(filePath);
                fileInfo.setFileName(originalFilename);
                fileInfo.setFileFormat(suffix);
                fileInfo.setFileSize(file.getSize());
                fileInfo.setNewFileName(newFileName);
            }

        } catch (NoSuchAlgorithmException | IOException | QSException e) {
            log.error(e.getMessage());
            throw new BaseException("文件上传失败!");
        }
        return fileInfo;
    }


    public static FileInfo uploadFile(Bucket qyBucket, String qyBucketName, String qyZoneName, String base64Image) {
        FileInfo fileInfo = new FileInfo();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Date nowDate = DateUtils.getNowDate();
        String format = sdf.format(nowDate);
        byte[] imageBytes = Base64.getDecoder().decode(base64Image);


        Bucket.PutObjectInput input = new Bucket.PutObjectInput();
        try {
            InputStream body = new ByteArrayInputStream(imageBytes);
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            // 这里只起示例作用, 如果 body size 有可能非常大, 按一定 size 做拆分以分段
            // 上传形式来分 part 计算 md5 上传才是比较经济的方式.
            byte[] data = body.readAllBytes();
            String contentMD5 = Base64.getEncoder().encodeToString(md5.digest(data));
            input.setContentMD5(contentMD5);
            // 此时 stream 已经被 consume 掉, 但对象存储 server side 也需要读取 body 内容,
            //  所以在 setBodyInputStream 之前,  可以通过:
            //  1. 流已经读取为 bytes array, 直接构造 ByteArrayInputStream 即可;
            body = new ByteArrayInputStream(data);
            //  2. 如果流支持 markSupported(), 可以重设到流的开始.
            //  下面是方式 2 的示例:
            body.reset();
            input.setBodyInputStream(body);
//            String originalFilename = file.getOriginalFilename();
            String originalFilename = "image.jpg";
            String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            String id = UUID.randomUUID().toString();
            String newFileName = id + "." + suffix;
            newFileName = format + "/" + newFileName;

            Bucket.PutObjectOutput output = qyBucket.putObject(newFileName, input);
            log.info("output: " + output);
            System.out.println(output.getStatueCode());
            if (output.getStatueCode() == 201) {
                log.info("文件上传成功!");
                String filePath = String.format("https://%s.%s.qingstor.com/%s", qyBucketName, qyZoneName, newFileName);

                fileInfo.setFilePath(filePath);
                fileInfo.setFileName(originalFilename);
                fileInfo.setFileFormat(suffix);
//                fileInfo.setFileSize(file.getSize());
                fileInfo.setNewFileName(newFileName);
            }

        } catch (NoSuchAlgorithmException | IOException | QSException e) {
            log.error(e.getMessage());
            throw new BaseException("文件上传失败!");
        }
        return fileInfo;
    }


}
